#include "Generator.h"

namespace zbp
{

void Generator::generate_graph(SimpleGraph &graph, CompleteGraph<int> &cgraph, BoostEdge* boost_edges, int* boost_weights,
	int nodes_count, int adjacency_count, int max_weight, int negative_amount, bool is_directed)
{	
	int *neighbours = new int[adjacency_count];
	int neighbour;
	double *neighbours_weight = new double[adjacency_count];
	int counter = 0;
	int boost_counter = 0;
	int i, j;	
		
	srand(646);

	if (adjacency_count >= nodes_count)
	{
		adjacency_count = nodes_count - 1;
	}

	for (i = 0; i < nodes_count; i++)
	{
		while (counter != adjacency_count)
		{				
			neighbour = rand() % nodes_count;
			if (neighbour != i && this->check_values(neighbours, neighbour, counter))
			{
				neighbours[counter] = neighbour;
				neighbours_weight[counter] = rand() % max_weight + 1;				
				counter++;
			}
		}

		for (j = 0; j < adjacency_count; j++)
		{				
			if ((rand() % negative_amount) == 1)
			{
				//neighbours_weight[j] *= -1;
			}
			
			graph.add_edge(i, neighbours[j], neighbours_weight[j]);
			
			cgraph.add_edge(i, neighbours[j], neighbours_weight[j]);

			boost_edges[boost_counter].first = i;
			boost_edges[boost_counter].second = neighbours[j];
			boost_weights[boost_counter] = neighbours_weight[j];
			boost_counter++;
		}

		counter = 0;
	}				
}

void Generator::add_nodes(SimpleGraph &graph, CompleteGraph<int> &cgraph, BoostEdge* boost_edges, int* boost_weights,
	int nodes_count, int adjacency_count, int max_weight, int negative_amount, int to_add)
{
	int *neighbours = new int[adjacency_count];
	int neighbour;
	double *neighbours_weight = new double[adjacency_count];
	int counter;
	int boost_counter = nodes_count;
	int i, j;	
		
	srand(NULL);

	int new_nodes_count = nodes_count + to_add;
	//cgraph.set_nodes_count(new_nodes_count);

	if (adjacency_count >= new_nodes_count)
	{
		adjacency_count = new_nodes_count - 1;
	}

	for (i = nodes_count; i < new_nodes_count; i++)
	{
		counter = 0;
		while (counter != adjacency_count)
		{				
			neighbour = rand() % new_nodes_count;
			if (neighbour != i && this->check_values(neighbours, neighbour, counter))
			{
				neighbours[counter] = neighbour;
				neighbours_weight[counter] = rand() % max_weight + 1;				
				counter++;
			}
		}
		for (j = 0; j < adjacency_count; j++)
		{				
			if ((rand() % negative_amount) == 1)
			{
				//neighbours_weight[j] *= -1;
			}
			
			graph.add_edge(i, neighbours[j], neighbours_weight[j]);
			cgraph.add_edge(i, neighbours[j], neighbours_weight[j]);

			boost_edges[boost_counter].first = i;
			boost_edges[boost_counter].second = neighbours[j];
			boost_weights[boost_counter] = neighbours_weight[j];
			boost_counter++;
		}		
	}
}

bool Generator::check_values(int* array, int value, int i)
{
	for (int j = 0; j < i; j++)
	{
		if (array[j] == value)
		{
			return false;		
		}	
	}

	return true;
}

}